﻿using System;
using System.Numerics;

namespace UtilZ.Dotnet.Ex.Base
{
    /// <summary>
    /// Enumerable扩展类
    /// </summary>
    public partial class EnumerableEx
    {
        #region 最大值求取扩展

        /// <summary>
        /// 返回byte序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static byte Max(Span<byte> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回sbyte序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static sbyte Max(Span<sbyte> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回short序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static short Max(Span<short> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回ushort序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static ushort Max(Span<ushort> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回int序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static int Max(Span<int> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回uint序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static uint Max(Span<uint> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回long序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static long Max(Span<long> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回ulong序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static ulong Max(Span<ulong> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回float序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static float Max(Span<float> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回double序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static double Max(Span<double> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回decimal序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static decimal Max(Span<decimal> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        /// <summary>
        /// 返回BigInteger序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static BigInteger Max(Span<BigInteger> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var max = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] > max)
                {
                    max = source[i];
                }
            }
            return max;
        }

        #endregion



        //****************************************************************************************************
        //****************************************************************************************************




        #region 最小值求取扩展Span



        /// <summary>
        /// 返回byte序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static byte Min(Span<byte> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回sbyte序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static sbyte Min(Span<sbyte> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回short序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static short Min(Span<short> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回ushort序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static ushort Min(Span<ushort> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回int序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static int Min(Span<int> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回uint序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static uint Min(Span<uint> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回long序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static long Min(Span<long> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回ulong序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static ulong Min(Span<ulong> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回float序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static float Min(Span<float> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回double序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static double Min(Span<double> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回decimal序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static decimal Min(Span<decimal> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        /// <summary>
        /// 返回BigInteger序列中指定位置以及指定元素个数中数据最小值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>最小值</returns>
        public static BigInteger Min(Span<BigInteger> source)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            var min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                if (source[i] < min)
                {
                    min = source[i];
                }
            }
            return min;
        }

        #endregion





        //****************************************************************************************************
        //****************************************************************************************************

        #region 最大最小值求取扩展


        /// <summary>
        /// 返回byte序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<byte> source, out byte min, out byte max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回sbyte序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<sbyte> source, out sbyte min, out sbyte max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回short序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<short> source, out short min, out short max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回ushort序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<ushort> source, out ushort min, out ushort max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回int序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<int> source, out int min, out int max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回uint序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<uint> source, out uint min, out uint max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回long序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<long> source, out long min, out long max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回ulong序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<ulong> source, out ulong min, out ulong max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回float序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<float> source, out float min, out float max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回double序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<double> source, out double min, out double max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回decimal序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<decimal> source, out decimal min, out decimal max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        /// <summary>
        /// 返回BigInteger序列中指定位置以及指定元素个数中数据最小值和最大值
        /// </summary>
        /// <param name="source">序列</param>
        /// <param name="min">输出的最小值</param>
        /// <param name="max">输出的最大值</param>
        public static void MinMax(Span<BigInteger> source, out BigInteger min, out BigInteger max)
        {
            if (source.Length < 1)
            {
                throw new ArgumentOutOfRangeException("没有元素");
            }

            max = min = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                var temp = source[i];
                if (temp < min)
                {
                    min = temp;
                }

                if (temp > max)
                {
                    max = temp;
                }
            }
        }

        #endregion


        //****************************************************************************************************
        //****************************************************************************************************



        #region 平均值求取扩展

        /// <summary>
        /// 计算byte序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<byte> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算sbyte序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<sbyte> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算short序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<short> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算ushort序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<ushort> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算int序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<int> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算uint序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<uint> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算long序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<long> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算ulong序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<ulong> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return (double)sum / source.Length;
        }

        /// <summary>
        /// 计算float序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<float> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return sum / source.Length;
        }

        /// <summary>
        /// 计算double序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static double Average(Span<double> source)
        {
            if (source.Length < 1)
            {
                return default(double);
            }

            double sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return sum / source.Length;
        }

        /// <summary>
        /// 计算decimal序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static decimal Average(Span<decimal> source)
        {
            if (source.Length < 1)
            {
                return default(decimal);
            }

            decimal sum = source[0];
            checked
            {
                for (int i = 1; i < source.Length; i++)
                {
                    sum += source[i];
                }
            }

            return sum / source.Length;
        }

        /// <summary>
        /// 计算BigInteger序列中指定位置以及指定元素个数的平均值
        /// </summary>
        /// <param name="source">序列</param>
        /// <returns>平均值</returns>
        public static BigInteger Average(Span<BigInteger> source)
        {
            if (source.Length < 1)
            {
                return default(BigInteger);
            }

            BigInteger sum = source[0];
            for (int i = 1; i < source.Length; i++)
            {
                sum += source[i];
            }
            return sum / source.Length;
        }

        #endregion

    }


}
